{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Programming onboard peripherals"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## LEDs, switches and buttons\n",
    "This notebook can be run with the PYNQ-Z1 or PYNQ-Z2. Both boards have four green LEDs (LD0-3), 2 multi colour LEDs (LD4-5), 2 slide-switches (SW0-1) and 4 push-buttons (BTN0-3) that are connected to the Zynq’s programmable logic."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that there are additional push-buttons and LEDs on the board, but these are used for specific functions (Power LED, PS reset button etc) and are not user accessible.\n",
    "\n",
    "The IO can be controlled directly from Python. To demonstrate this, we first import the LED, Switch and Button classes from the module pynq.board:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pynq.overlays.base import BaseOverlay\n",
    "base = BaseOverlay(\"base.bit\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Controlling an LED\n",
    "Now we can create an instance of each of these classes and use their methods to manipulate them. Let’s start by instantiating a single LED and turning it on and off."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pynq.lib import LED, Switch, Button"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "led0 = base.leds[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "led0.on()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Check the board and confirm the LED is on."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "led0.off()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let’s then toggle _led0_ using the sleep() method from the _time_ package to see the LED flashing. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "led0 = base.leds[0]\n",
    "for i in range(20):\n",
    "    led0.toggle()\n",
    "    time.sleep(.1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example: Controlling all the LEDs, switches and buttons\n",
    "\n",
    "\n",
    "The example below creates 3 separate lists, called _leds_, _switches_ and _buttons_."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Set the number of Switches\n",
    "MAX_LEDS =4\n",
    "MAX_SWITCHES = 2\n",
    "MAX_BUTTONS = 4\n",
    "\n",
    "leds = [base.leds[index]) for index in range(MAX_LEDS)]\n",
    "switches = [base.switches[index]) for index in range(MAX_SWITCHES)] \n",
    "buttons = [base.buttons[index]) for index in range(MAX_BUTTONS)] \n",
    "\n",
    "# Create lists for each of the IO component groups\n",
    "for i in range(MAX_LEDS):\n",
    "    leds[i] = base.leds[i])              \n",
    "for i in range(MAX_SWITCHES):\n",
    "    switches[i] = base.switches[i])      \n",
    "for i in range(MAX_BUTTONS):\n",
    "    buttons[i] = base.buttons[i]) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, all LEDs are set to off. Then each switch is read, and if a switch is in the on position, the corresponding led is turned on. You can execute this cell a few times, changing the position of the switches on the board."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# LEDs start in the off state\n",
    "for i in range(MAX_LEDS):\n",
    "    leds[i].off()\n",
    "\n",
    "# if a slide-switch is on, light the corresponding LED\n",
    "for i in range(MAX_LEDS):                  \n",
    "    if switches[i%2].read():                                    \n",
    "        leds[i].on()\n",
    "    else:\n",
    "        leds[i].off()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The last part toggles the corresponding led (on or off) if a pushbutton is pressed. You can execute this cell a few times pressing different pushbuttons each time. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# if a button is depressed, toggle the state of the corresponding LED\n",
    "for i in range(MAX_LEDS):\n",
    "    if buttons[i].read():\n",
    "        leds[i].toggle()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Next steps\n",
    "\n",
    "If you have time, write your own program to:\n",
    "1. Turn on/off a single LED when a button is pressed\n",
    "2. Shift the LED pattern when another button is pressed (the shift direction is determined by the value of the dip switch)\n",
    "3. Toggle/Flash the LEDs for 5 seconds when another button is pressed\n",
    "4. Change the delay between toggle when the last button is pressed. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "celltoolbar": "Raw Cell Format",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
